home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
AUDIOPLAYERS
/
AMP
/
!Amp
/
Docs
/
TimGuide
< prev
next >
Wrap
Text File
|
1999-02-22
|
32KB
|
1,046 lines
————————————————————————————————————————————————————————————————————————————————
TimPlayer v0.88, © André Timmermans 1996-1998
————————————————————————————————————————————————————————————————————————————————
Introduction
————————————
TimPlayer is a RISC OS soundtrack player that supports the following formats:
- Standard MODs.
- PC MODs (with more than 4 channels, I even found a 28 channels one).
- Multi Tracker Modules (MTM).
- ScreamTracker 3 Modules (S3M): ADPCM samples and adlib samples not
supported, but I have never found a file which used them.
- Fast Tracker 2 Modules (XM).
- Impulse Tracker Modules (IT), including support for packed samples and
virtual channels.
You are free to use this module with in own applications (or demos) as long
as users are able to replace the module with more recent versions in case
the current version fails to work on new hardware or new version of RISC OS.
The main features are turned toward sound quality rather than speed:
- 32-bit internal precision for mixing, dithered to 8-bit or 16-bit.
- In 8-bit mode, the logarithmic buffers are generated using a linear to
logarithmic translation table with 12 significant bits instead of the
usual 8-bit table found in most players (quiet sounds are much clearer).
- Linear interpolation is used for resampling.
- Dynamic Gain Control allows to boost the volume level of songs with many
channels while ensuring that no clipping occurs.
- Volume scaling is done with multiplications, not approximated by shifts.
- Volume ramping: instead of jumping from one note volume to the other, the
player will use a volume ramp of a few ms at the start of every frame,
which will remove most of the pops and clicks in the sound.
- Supports multiple effects on the same channel.
- Provides timing (in ms) of song position and the song duration.
- Accept Surround effect (not Prologic) which sends the sound to the tiny
lateral amplifiers instead of the big ones of your HiFi installation.
- Performs a limitation of the note polyphony when the CPU usage becomes too
high, to prevent freezing the computer. When a song requests to play more
notes than allowed by the note polyphony, the mixing routines will only
play the notes with the highest volume.
Hardware requirements
—————————————————————
- An A5000 is enough for 4 channels MODs, a StrongARM is required for songs
with 64 channels.
- Either the original 8-bit sound or a 16-bit card.
Contacts
————————
You can contact me using email at:
tim@swn.sni.be (which I can only access between Monday and Thursday).
or using smail address:
Timmermans André
Rue du Vert Coron, 17
7600 Péruwelz
Belgium
Sound quality setup
———————————————————
All the parameters controlling the sound output are tuned using:
SYS "TimPlayer_Configure", param id, param value
The following parameters are currently defined:
* Mixing quality:
This is the duration (in microseconds) a digital sample value is maintained
on the DAC (Digital/Analog Converter) that produces the sound. The smaller
this duration is, the faster it will be possible to change the output signal
and the better the higher frequencies in the signal will be reproduced.
For example a value of 24 µs will allow the signal to change at 41666 Hz.
* Sample interpolation:
This defines the way you play samples which have a frequency which differs
from the output frequency defined by the mixing quality. If for example you
which to play a sample defined at 20833 Hz with an output frequency of
41666 Hz, you will have to feed the DAC with 2 times (41666/20833) the
number of values defined in the sample. The simple way to is to feed the DAC
twice with the same sample value, but we can as well interpolate between the
successive values. In our example I could feed the DAC with the following
sequence: value 0, mean of value 0 & 1, value 1, mean of value 1 & 2, ...
There are many forms of interpolation but I defined only the one which takes
the less processing power, linear interpolation.
* Balance:
This defines the balance between the left and right speakers and allows you
to offset the produced signal to the left or the right.
* Stereo separation:
This defines the rate at which a signal moves from a central position to the
left or the right. Increasing the rate will produce "spatial" sound,
dropping to zero will produce a mono signal and negative rate will invert
the stereo.
* Volume ramping:
You may have noticed that sometimes while playing the speakers produces pops
or clicks. This is produced by brutal changes in the signal received by
the speakers and has various causes. The most obvious cause is the use of
samples which contains such brutal changes and composers quickly learn to
avoid such samples but otherwise not much can be done to avoid the noises.
The other cause is changing the volume at which a note is played when using
a volume effect or a note cut (and playing a new note in a channel usually
cuts the previous note) but here instead of changing the volume in one go
we can use a ramp of a few milliseconds to smooth the change and that way
avoid generating pops and clicks.
Current limits
——————————————
- 64 logical channels.
- 255 samples.
- 255 instruments.
- 256 rows in a pattern.
- Unlimited number of patterns and sequence length.
- Note range from C-0 to B-9.
Not implemented
———————————————
- MOD effect EF (invert loop).
- IT flag 'link E|F and G memory'.
- IT usage of a different memory for volume slides in volume column.
- IT volume and panning swing.
- IT filters.
- IT MIDI parameters.
Timing explained
————————————————
Due to the nature of soundtracks, timing is not a straightforward issue.
So first let me explain briefly how a soundtrack is played:
1. A song is composed of a sequence of patterns which are played in turn.
Example the sequence 1-3-5-1-1-2 means play pattern nr 1, then pattern
nr 3 then nr 5, then nr 1 again, etc.
2. Each pattern is divided in n rows (64 usually) which are played in turn.
A row contains information to apply to each defined channel: instrument,
note to play, volume, panning, commands (effects) to apply. When a row is
played, first the row is decoded, then commands are applied and the note
is maintained for a given duration called a frame (or sometimes a tick).
Then commands are re-applied and the note is maintained for the same
duration. Then ...
The duration of a row is determined by two parameters:
- the Tempo or number of beats per minutes (125 by default)
and the relation: nr of frames/sec = 0.4 * tempo.
- the Speed or number of frames per row (6 by default).
So, the duration of a song could simply be:
sum for each pattern in the sequence of "nr of rows * speed * 0.4 * tempo".
The problem is the existence of special commands that interferes with this,
such as:
- Set Tempo, to alter the tempo
- Set Speed, to alter the speed
- Pattern break, to stop playing the current pattern and to go in row x
of the next pattern in the sequence
- Sequence Jump, to stop playing current pattern and to go in row 0
of pattern at sequence index x.
- Loop, to loop x times on a set of rows.
The best way I have found is to perform the song without actually playing
but applying only the above commands, adding together the resulting frame
durations and storing this time index at the start of each position in the
pattern sequence until I reach a the end of a sequence or I branch to
a sequence position I have already timed.
As this may not cover all the positions in the sequence (for example all the
songs in the game Lemmings are stored in the same soundtrack and are played
by moving to different looping sequence fragments) I then move to the first
untimed sequence position and continue the timing from that point. And again
and again until every sequence position is timed. The final timing obtained
is the song duration reported by TimPlayer_SongInfo.
During real playback I maintain a timer that can be obtained on return of
TimPlayer_SongPosition. The timer is reset at every sequence position change
to the time index store for that position, then time is added normally
while the pattern is played.
Those of you with some knowledge of how soundtracks works will noticed
immediately the remaining problems:
- by combining Pattern Break and Sequence Jumps it is possible to perform 2
or more sets of different rows of the same pattern position (and I have
only timed one of them) or to perform the same set with different
tempo/speed settings.
- when the user decide to skip a part of the song he may bypass some
Set Tempo/Set Speed, which means that the song will then continue
to play with abnormal tempo/speed settings.
TroubleShooting
———————————————
* Processing power:
Those with less faster machine should be warned that the CPU usage can be
quite high: at 24 µs, above 1% of CPU per channel on my SA RPC
at 72 µs, Cache off, 4 channels grabs 60% of CPU
As a result playing songs with many channels on slow machines would result
in grabbing 100% of the CPU, you would never have the control back and be
forced to reset the machine. To prevent this the player is timing the mixing
routines and when it detects that it's taking more time to fill the sound
DMA buffers than the duration they represent, the note polyphony is
decreased to reduce the processor usage.
When a song requests to play more notes than allowed by the note polyphony,
the mixing routines will choose to play only the notes with the highest
volume.
Basically on a ARM 6 machine, with a mixing quality of 24 µs you cannot go
above a polyphony of 11-12 notes.
* One possible problem is that I use the IOCTimer1 so it may conflict with
Acorn's TimeCode module and a few others.
* Bangs when starting to play, pausing or stopping a song:
I have noticed that altering the stereo position of hardware channels tends
to produce noises on 8-bit hardware, which often leads to a small bang when
at song startup I switch from 1 to 2 channels and reconfigure the stereo
positions. As anyone found a way to avoid it?
————————————————————————————————————————————————————————————————————————————————
SWI Interface
————————————————————————————————————————————————————————————————————————————————
The SWI interface as been partially rewritten (I told you it was still subject
to change without notice). From version 0.86, changes to the interface are
done without introducing incompatibilities.
In all the following commands every numbering (patterns, rows, ...) usually
starts at value 0. The only exceptions are:
1) Samples/instruments where 0 means no sample/instrument, so numbering starts
with 1.
2) Note values cover 10 octaves and each octave is divided equally
in 12 semitones. The semitones in increasing order of frequency
are noted: C C# D D# E F F# G G# A A# B
The note C of octave 5 (C-5) is the central note i.e. is the
one which plays the sample at its default frequency and was given
the number 64. This gives a valid range of 4 (C-0) to 123 (B-9).
Warning: on SWI exit flags are corrupted
TimPlayer_Version &51380
————————————————————————
Returns the current version of the player.
On entry
-
On exit
R0 = version * 100
TimPlayer_Configure &51381
——————————————————————————
Reads or alters the player's configuration.
On entry
R0 = configuration code
R1 = configuration value
On exit
R1 = current configuration value
Use
* Mixer configuration codes:
0 - R1 = mixing quality in µs [24, 32, 40, 48, 46, 64, 72], -1 to read
1 - R1 = interpolation, 0 off, 1 linear, -1 read
2 - R1 = balance [left 0, right 255], -1 to read
3 - R1 = stereo separation [-1024,1024], 256 is normal, 1<<31 to read
4 - R1 = force usage of the 8-bit sound system, 0 off, 1 on, -1 read
(not for normal use, provided mainly for tests)
* Tracker configuration codes:
256 - R1 = volume ramping, 0 off, 1 on, -1 read
257 - R1 = ignore loops in last pattern, 0 off, 1 on, -1 read
258 - R1 = ignore end of sequence markers, 0 off, 1 on, -1 read
TimPlayer_SongLoad &51382
—————————————————————————
Loads a soundtrack file in memory, sets the playback position to the start
of first pattern in the sequence and returns an logical handle for the song.
On entry
R1 = filename pointer
On exit
R0 = song handle
Use
Up to now the player only supports one loaded song at a time and replaces
any previously loaded song in memory by the new one. However this behaviour
may change in the future and you should always use TimPlayer_SongUnload
to remove a song from memory instead of expecting TimPlayer_SongLoad to
do it for you.
Related SWIs
TimPlayer_SongUnload
TimPlayer_SongUnload &51383
———————————————————————————
Removes a song from memory.
On entry
R0 = song handle
On exit
-
Related SWIs
TimPlayer_SongLoad
TimPlayer_SongPlay &51388
—————————————————————————
Resumes the playback from the current playback position.
On entry
R0 = song handle
On exit
-
Related SWIs
TimPlayer_SongPause, TimPlayer_SongStop
TimPlayer_SongPause &51389
——————————————————————————
Pauses the playback of the song.
On entry
R0 = song handle
On exit
-
Related SWIs
TimPlayer_SongPlay, TimPlayer_SongStop
TimPlayer_SongStop &5138A
—————————————————————————
Stops the playback of the song, reset all global and channel parameters
and sets the playback position to the start of the first pattern in the
sequence.
On entry
R0 = song handle
On exit
-
Related SWIs
TimPlayer_SongPlay, TimPlayer_SongPause
TimPlayer_SongPosition &5138B
—————————————————————————————
Reads or alter the playback position of the song.
On entry
R0 = song handle
R1 = new position in the sequence [0, nr of orders[, -1 to read
On exit
R1 = current position in the sequence [0, nr of orders[
R2 = current row in pattern [0, pattern length[
R3 = current pattern [0, nr of patterns[
R4 = number of rows in the current pattern [0, 255]
R5 = time index (in ms)
TimPlayer_SongVolume &5138C
———————————————————————————
Reads or alter the volume level of the song.
On entry
R0 = song handle
R1 = new volume [0, 256], -1 to read
On exit
R1 = current volume [0, 256]
TimPlayer_SongInfo &51390
—————————————————————————
Provides general information on the song.
On entry
R0 = song handle
On exit
R1 = number of channels [0, 64]
R2 = number of orders in sequence [0, ]
R3 = pointer to sequence table (4 bytes values)
R4 = number of patterns [0, ]
R5 = number of instruments [0, 255]
R6 = number of samples [0, 255]
R7 = flags
song_flag_linear * &00000001
song_flag_instruments * &00000002
TimPlayer_SongTexts &51391
——————————————————————————
Provides general textual information on the song.
On entry
R0 = song handle
On exit
R1 = song title, pointer to a 0 terminated string.
R2 = song author, pointer to a 0 terminated string.
R3 = song type, pointer to a 0 terminated string.
R4 = length of the song comments.
R5 = song comments, pointer to a sequence of control terminated lines.
TimPlayer_SongInitialSettings &51392
————————————————————————————————————
Provides the initial settings of the song's general parameters.
On entry
R0 = song handle
On exit
R1 = initial speed [1, 31]
R2 = initial tempo [32, 255]
R3 = initial global volume [0, 256]
Do not confuse it with the volume set with TimPlayer_SongVolume!
R4 = restart position [0, nr of orders[
TimPlayer_ChannelInitialSettings &51393
———————————————————————————————————————
Provides the initial settings of a song channel.
On entry
R0 = song handle
R1 = channel number [0, nr of channels[
On exit
R2 = volume [0, 256]
R3 = panning [0, 255], 256 is surround
TimPlayer_SongPlayInfo &51394
—————————————————————————————
On entry
R0 = song handle
On exit
R1 = min pitch (defined once and for all by the soundtrack type)
R2 = max pitch (defined once and for all by the soundtrack type)
R3 = corrupted
R4 = Time Length (in ms)
R5 = Current max nr of playing channels seen.
This can be greater than nr of channels for ITs using
instruments with New Note Action != 'note cut'.
TimPlayer_SampleInfo &513A0
———————————————————————————
Reads a sample's general information.
On entry
R0 = song handle
R1 = sample nr [1, nr of samples]
On exit
R2 = sample size (in values, not bytes)
R3 = sample data pointer
R4 = sample flags
smp_type_unsigned * &00000001 (converted to signed on loading)
smp_type_stereo * &00000002 (not supported)
smp_type_16bit * &00000004
smp_type_loop * &00000008
smp_type_loop_bidi * &00000010
smp_type_sustain * &00000020
smp_type_sustain_bidi * &00000040
smp_type_set_panning * &00000080
smp_type_surround * &00000100
R5 = sample name, pointer to 0 terminated string
R6 = sample filename, pointer to 0 terminated string
TimPlayer_SampleMisc &513A1
———————————————————————————
Reads various parameters of a sample.
On entry
R0 = song handle
R1 = sample nr [1, nr of samples]
On exit
R2 = sample default volume [0, 256]
R3 = sample scale volume [0, 256]
R4 = sample panning [0, 255]
used only if smp_type_set_panning is on
and smp_type surround is off
R5 = sample frequency (Hz)
R6 = sample finetune
R7 = sample relative tone (in semitones)
TimPlayer_SampleLoops &513A2
————————————————————————————
Reads a sample's looping information.
On entry
R0 = song handle
R1 = sample nr [1, nr of samples]
On exit
R2 = sample loop start
R3 = sample loop end
R4 = sample sustain loop start
R5 = sample sustain loop end
The values returned are logical offset from the start of the sample.
TimPlayer_SampleVibrato &513A3
——————————————————————————————
Reads a sample's auto-vibrato parameters.
On entry
R0 = song handle
R1 = sample nr [1, nr of samples]
On exit
R2 = sample vibrato type
cmd_vibrato_type_sin * &0
cmd_vibrato_type_square * &1
cmd_vibrato_type_rampdown * &2
cmd_vibrato_type_rampup * &3
cmd_vibrato_type_random * &4
R3 = sample vibrato depth [0, 255]
R4 = sample vibrato speed [0, 255]
R5 = sample vibrato rate [0, 255]
TimPlayer_InstInfo &513A8
—————————————————————————
Reads an instrument's general information.
On entry
R0 = song handle
R1 = instrument nr [1, nr of instruments]
On exit
R2 = name, pointer to 0 terminated string
R3 = filename, pointer to 0 terminated string
R4 = note mapping table 128 byte pairs (note, sample nr)
R5 = flags
inst_flag_set_panning * &1
inst_flag_surround * &2
R6 = New note action
note_action_cut * 0
note_action_off * 1
note_action_fade * 2
note_action_continue * 3
R7 = Duplicate check type
inst_DCT_off * 0
inst_DCT_note * 1
inst_DCT_sample * 2
inst_DCT_instrument * 3
R8 = Duplicate note action
see R4
TimPlayer_InstVolume &513A9
———————————————————————————
Reads an instrument's volume information.
On entry
R0 = song handle
R1 = instrument nr [1, nr of instruments]
On exit
R2 = scale volume [0, 256]
R3 = fadeout volume [0, 65536]
R4 = swing
TimPlayer_InstPanning &513AA
————————————————————————————
Reads an instrument's panning information.
On entry
R0 = song handle
R1 = instrument nr [1, nr of instruments]
On exit
R2 = panning [0, 255]
R3 = swing
R4 = pitch-pan separation [0, 128]
R5 = pitch-pan central note [4 (C-0), 123 (B-9)]
TimPlayer_InstVolumeEnvelope &513AC
———————————————————————————————————
Reads an instrument's volume envelope.
On entry
R0 = song handle
R1 = instrument nr [1, nr of instruments]
On exit
R2 = nr of points
R3 = pointer to table of 2bytes pairs (frame nr, volume)
R4 = flags
envelope_flag_on * 1
envelope_flag_sustain * 2
envelope_flag_loop * 4
R5 = loop start point
R6 = loop end point
R7 = sustain start point
R8 = sustain end point
Use
The volume envelope modulates the instrument's volume in the frames that
follows the start of a note. It is described graphically as a sequence
of lines segments from one point to the following. Volume values are in
range [0, 256] and values for frames between points are calculated by using
linear interpolation.
TimPlayer_InstPanningEnvelope &513AD
————————————————————————————————————
Reads an instrument's panning envelope.
On entry
R0 = song handle
R1 = instrument nr [1, nr of instruments]
On exit
R2 = nr of points
R3 = pointer to table of 2bytes pairs (frame nr, panning)
R4 = flags
envelope_flag_on * 1
envelope_flag_sustain * 2
envelope_flag_loop * 4
R5 = loop start point
R6 = loop end point
R7 = sustain start point
R8 = sustain end point
Use
The panning envelope modulates the instrument's panning in the frames that
follows the start of a note. It is described graphically as a sequence
of lines segments from one point to the following. Panning values are in
range [0, 255] and values for frames between points are calculated by using
linear interpolation. Values are then applied using the following formula:
panning = panning + (128 - abs(panning - 128)) * (envelope value - 128)/128
which means that the variation is not applied at full scale but is
proportional to the distance between the note's panning and the nearest
extremity (left or right).
TimPlayer_InstPitchEnvelope &513AE
——————————————————————————————————
Reads an instrument's pitch envelope.
On entry
R0 = song handle
R1 = instrument nr [1, nr of instruments]
On exit
R2 = nr of points
R3 = pointer to table of 2bytes pairs (frame nr, pitch offset)
R4 = flags
envelope_flag_on * 1
envelope_flag_sustain * 2
envelope_flag_loop * 4
R5 = loop start point
R6 = loop end point
R7 = sustain start point
R8 = sustain end point
Use
The pitch envelope modulates the instrument's pitch in the frames that
follows the start of a note. It is described graphically as a sequence
of lines segments from one point to the following. Pitch values are in
range [-64, 64] and values for frames between points are calculated by
using linear interpolation.
TimPlayer_SongParams &513B8
———————————————————————————
Reads the current song global playback parameters.
On entry
R0 = song handle
On exit
R1 = current speed [0, 31]
R2 = current tempo [32, 255]
R3 = current global volume [0, 256]
TimPlayer_ChannelParams &513B9
——————————————————————————————
Reads a song channel playback parameters.
On entry
R0 = song handle
R1 = channel nr [0, nr of channels[
R2 = 16-bit buffer pointer or 0
R3 = buffer len (bytes)
On exit
R2 = instrument nr (0 if nothing played)
R3 = pitch in 1/65536 of default pitch (0 if nothing played)
R4 = if R2 != 0 on input
buffer peak value [0,&7FFF]
else
note volume [0, &10000]
R5 = if R2 != 0 on input
buffer mean value [0,&7FFF]
else
note volume [0, &10000]
R6 = panning [0 (left), 255 (right)], 256 for surround
TimPlayer_VChannelParams &513BA
———————————————————————————————
Reads a virtual channel playback parameters.
On entry
R0 = song handle
R1 = vchannel nr
R2 = 16-bit buffer pointer or 0
R3 = buffer len (bytes)
On exit
R2 = instrument nr
R3 = pitch in 1/65536 of default pitch
R4 = if R2 != 0 on input
buffer peak value [0,&7FFF]
else
note volume [0, &10000]
R5 = if R2 != 0 on input
buffer mean value [0,&7FFF]
else
note volume [0, &10000]
R6 = panning [0, 255], 256 for surround
R7 = channel nr on which the note was started,
bit 31 is also set if it is a 'past note'
-1 if not playing
TimPlayer_ChannelStatus &513BB
——————————————————————————————
On entry
R0 = song handle
R1 = channel nr [0, nr of channels[
R2 = actions
channel described in R1
bit 0: alter status: 1 yes, 0 no
bit 1: new status: 1 play, 0 mute
channels other than the one described in R1
bit 2: alter status: 1 yes, 0 no
bit 3: new status: 1 play, 0 mute
On exit
R3 = channel status (1 play, 0 mute)
————————————————————————————————————————————————————————————————————————————————
History
————————————————————————————————————————————————————————————————————————————————
16-04-98 Reset song parameters at restart pos or pos 0
18-04 IT packed samples decoding is working 8)
19-04 Inverted effects of linear pitch slide up/down
Modified Note Off fadeout conditions
Moved all XM notes one halftone down
29-04 IT effect V as range 0-128 instead of 0-64!
Modified Note Off fadeout conditions once again
Some trials to speed up things on non-SA
03-05 Incorrect test, never played last defined instrument !!!
Support of XM command L: set envelope pos
10-05 IT envelope flags loop and sustain were inverted
24-05 IT virtual channels
30-05 support for 1/4 stereo pairs
05-06 support for 16-bit hardware
06-06 Bug in IT volume command M.
08-06 option to disable interpolation
Version 0.81
————————————
10-06-98 Big bug introduced the 08-06
Version 0.82
————————————
13-06-98 Corrected arpeggio (1 octave too high)
15-06 S3M files: pattern parapointer of 0 means empty pattern of 64 rows
16-bit hardware, stereo was inverted
16-06 MOD files loading: if byte &3B7 value is not 127
search highest pattern nr from defined sequence only
and not the whole 128 bytes
MOD: Problems of cmd F00 with multiple F on a row
Version 0.83
————————————
17-06-98 S3M/IT: J00 is repeat last arpeggio
20-06 IT effect SAy (set sample high offset)
IT surround: play note as central pan but invert right buffer.
Another correction for Note Off.
21-06 Notes which go beyond the maximum allowed pitch must be cut
27-06 Yet another correction for Envelopes (Grrr).
01-07 XM: incorrect correction on 19-04, actually there was
a 1 haltone offset in instrument note mappings
Version 0.84
————————————
06-07-98 Tone portamento must not be applied on frame 0 for MOD, XM
07-07 Vibrato must not be applied on frame 0 except for IT with old flags
09-07 MOD files loading: byte &3B7 is restart pos, value 127
means not used. Scanning for highest pattern modified as follows:
nr of patterns = (file size - header - samples) DIV pattern size
if (nr of pat <= highest pat in seq) nr of pat = highest pat
if (nr of pat > highest pat of 128 bytes seq) nr of pat = highest pat
I hope this is now correct because I really start to hate
that stupid file format.
11-07 Linear pitch handler could be called after amiga one
15-07 06-07 change extended to S3M/IT
17-07 IT global volume slides should be twice finer
21-07 Envelopes with loops: do not play position of last env. point
but restart loop (I_can_fly.xm).
Version 0.85
————————————
05-08-98 Added support for MTMs.
06-08 Store name and filename of every samples and instruments.
07-08 Reorganised the SWIs and added a whole new batch of them
to provide access to every bit of information on the song.
12-08 Use now dynamic areas for memory management
18-08 Corrected error in sample autovibrato
18-08 Corrected error sample sustain loop
Version 0.86
————————————
23-08-98 Recoded set envelope pos effect which was totally incorrect
(not sure yet if it's 100% as it should be)
24-08 Implemented limitation of the number of mixing notes when CPU usage
gets to high (I use IOCTimer1 so Acorn's TimeCode may not like it).
30-08 Correction: keep only the latest jump/pattern break on a row
instead of the latest jump and the latest pattern break
30-08 Volume ramping option implemented, and instead of jumping from one
volume to the other, the player will use a volume ramping at the start
of every frame, which will remove some of the pops and clicks
in the sound.
06-09 Yet another little (but noisy) bug in set envelope pos effect.
18-09 Should not try to process envelope when use envelope is set
but no envelope is actually defined.
25-09 Removed another bug in autovibrato.
05-10 Volume ramping extended to fade cut notes.
25-10 Read IT volume envelopes for v < 2.00
28-10 Added Balance and Stereo Separation.
01-11 Removed Precalculated Gain Control which was both time consuming
at song loading and inefficient for amplifying songs with a large
number of channels. Automatic Gain Control in Modplug style replaces
it: pre-amplification according to the number channels and dynamic
attenuation when required to avoid clipping.
11-11 Added Configuration code 4 to be able to force usage of the 8-bit sound
system for 2 reasons:
- be able to check 8-bit mode without the need to remove my Mozart card
or hacking the module.
- prevent someone I know to do the same hack.
Version 0.87
————————————
20-11-98 Maximum wave amplitude for Gain Control was not updated on volume
changes during playback.
27-11 Bug in handling of envelopes which could return values out of range
if an instrument is replaced by another one during a tone portamento.
02-12 Mixing routines did not work in 16-bit mode on an ARM6.
03-12 Dynamic Gain Control muted sound definitely in volume was set to 0
then restored.
Version 0.88
————————————
18-12-98 Removed infinite loop in corrupted MOD loading.
25-12-98 Keep 'end of sequence markers' into account.
Implemented Configure codes 257, 258.
02-01-99 Yet another correction in autovibrato.
In XM, remove as many unused samples as possible to fit in the 255
samples limit (cf. "Pools of Poison").
03-01-99 Corrected bug in Set Past/New Note Action commands.
10-01-99 Recoded some parts so that in the future more than one song may be
loaded (or even played at the same time).
18-01-99 Split notes and channels in nearly independent entities, virtual
channels support is completely rewritten as a consequence.
21-01-99 Note related effects are now processed even if no note is playing
to ensure effects memory is up to date.
12-02-99 Slight bug implementation of 18-01.